package com.ash.tx.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.ash.tx.bean.Book;
import com.ash.tx.bean.User;
import com.ash.tx.dao.BookDao;
import com.ash.tx.dao.UserDao;
import com.ash.tx.service.UserService;
import com.ash.tx.util.TransactionTemplateUtils;

/**
 * 使用TransactionTemplate 编程式事务
 * 
 * @author Ashin
 *
 */
@Service("userServiceImpl3")
public class UserServiceImpl3 implements UserService {

    @Autowired
    private BookDao bookDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private PlatformTransactionManager txManager;

    @Override
    public void purchase(final User user, final Book book, final Integer num) {
        TransactionTemplate txTemplate = TransactionTemplateUtils.getDefaultTransactionTemplate(txManager);

        txTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                Book bookBought = bookDao.queryBook(book.getId());

                bookBought.setStockNum(bookBought.getStockNum() - num);

                if (bookBought.getStockNum() <= 0) {
                    throw new RuntimeException("book stock num is not enough");
                }

                // 减库存
                bookDao.updateBook(bookBought);

                // 减余额
                User userPurchase = userDao.queryUser(user.getId());

                userPurchase.setBalance(userPurchase.getBalance() - bookBought.getPrice() * num);

                if (userPurchase.getBalance() <= 0) {
                    throw new RuntimeException("balance is not enough");
                }

                userDao.updateUser(userPurchase);

            }
        });

    }

}
